home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 October: Mac OS SDK / Dev.CD Oct 96 SDK / Dev.CD Oct 96 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODFDev / Draw / Sources / DrawLink.cpp < prev    next >
Encoding:
Text File  |  1996-08-16  |  26.2 KB  |  804 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                DrawLink.cpp
  4. //    Release Version:    $ ODF 1 $
  5. //
  6. //    Author:                Henri Lamiraux
  7. //    Linking added by:    M.Boetcher
  8. //
  9. //    Copyright:            (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  10. //
  11. //========================================================================================
  12.  
  13. #include "ODFDraw.hpp"
  14.  
  15. #ifndef DRAWLINK_H
  16. #include "DrawLink.h"
  17. #endif
  18.  
  19. #ifndef DRAWCONT_H
  20. #include "DrawCont.h"
  21. #endif
  22.  
  23. #ifndef DEFINES_K
  24. #include "Defines.k"
  25. #endif
  26.  
  27. #ifndef DRAWPART_H
  28. #include "DrawPart.h"
  29. #endif
  30.  
  31. #ifndef DRAWSEL_H
  32. #include "DrawSel.h"
  33. #endif
  34.  
  35. #ifndef BASESHP_H
  36. #include "BaseShp.h"
  37. #endif
  38.  
  39. #ifndef BOUNDSHP_H
  40. #include "BoundShp.h"
  41. #endif
  42.  
  43. #ifndef LINESHP_H
  44. #include "LineShp.h"
  45. #endif
  46.  
  47. #ifndef OVALSHP_H
  48. #include "OvalShp.h"
  49. #endif
  50.  
  51. #ifndef RECTSHP_H
  52. #include "RectShp.h"
  53. #endif
  54.  
  55. #ifndef RRECTSHP_H
  56. #include "RRectShp.h"
  57. #endif
  58.  
  59. #ifndef TEXTSHP_H
  60. #include "TextShp.h"
  61. #endif
  62.  
  63. #ifndef GROUPSHP_H
  64. #include "GroupShp.h"
  65. #endif
  66.  
  67. #ifndef DRAWPRXY_H
  68. #include "DrawPrxy.h"
  69. #endif
  70.  
  71. // ----- Framework Includes -----
  72.  
  73. #ifndef FWLNKITE_H
  74. #include "FWLnkIte.h"
  75. #endif
  76.  
  77. #ifndef FWPXYITE_H
  78. #include "FWPxyIte.h"
  79. #endif
  80.  
  81. #ifndef FWFRAME_H
  82. #include "FWFrame.h"
  83. #endif
  84.  
  85. #ifndef FWINTER_H
  86. #include "FWInter.h"
  87. #endif
  88.  
  89. #ifndef FWITERS_H
  90. #include "FWIters.h"
  91. #endif
  92.  
  93. #ifndef FWPRTITE_H
  94. #include "FWPrtIte.h"
  95. #endif
  96.  
  97. #ifndef FWPRESEN_H
  98. #include "FWPresen.h"
  99. #endif
  100.  
  101. #ifndef FWPXYFRM_H
  102. #include "FWPxyFrm.h"
  103. #endif
  104.  
  105. #ifndef FWUTIL_H
  106. #include "FWUtil.h"
  107. #endif
  108.  
  109. #ifndef FWCLNINF_H
  110. #include "FWClnInf.h"
  111. #endif
  112.  
  113. #ifndef FWBARRAY_H
  114. #include "FWBArray.h"
  115. #endif
  116.  
  117. // ----- Foundation Includes -----
  118.  
  119. #ifndef FWORDCOL_H
  120. #include "FWOrdCol.h"
  121. #endif
  122.  
  123. #ifndef FWMEMMGR_H
  124. #include "FWMemMgr.h"
  125. #endif
  126.  
  127. // for FW_SOMEnvironment
  128. #ifndef FWSOMENV_H
  129. #include "FWSOMEnv.h"
  130. #endif
  131.  
  132. // ----- OpenDoc Includes -----
  133.  
  134. #ifndef SOM_Module_OpenDoc_StdProps_defined
  135. #include <StdProps.xh>
  136. #endif
  137.  
  138. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  139. #include <StdTypes.xh>
  140. #endif
  141.  
  142. #ifndef SOM_ODStorageUnit_xh
  143. #include <StorageU.xh>
  144. #endif
  145.  
  146. #ifndef SOM_ODUndo_xh
  147. #include <Undo.xh>
  148. #endif
  149.  
  150. #ifndef SOM_ODSession_xh
  151. #include <ODSessn.xh>
  152. #endif
  153.  
  154. #ifndef SOM_ODLink_xh
  155. #include <Link.xh>
  156. #endif
  157.  
  158. #ifndef SOM_ODLinkSpec_xh
  159. #include <LinkSpec.xh>
  160. #endif
  161.  
  162. #ifndef SOM_ODLinkSource_xh
  163. #include <LinkSrc.xh>
  164. #endif
  165.  
  166. //========================================================================================
  167. // Runtime Information
  168. //========================================================================================
  169.  
  170. #ifdef FW_BUILD_MAC
  171. #pragma segment odfdraw
  172. #endif
  173.  
  174. FW_DEFINE_AUTO(CDrawPublishLinkCollection)
  175. FW_DEFINE_AUTO(CDrawPublishLinkCollectionIterator)
  176. FW_DEFINE_AUTO(CDrawSubscribeLinkCollection)
  177. FW_DEFINE_AUTO(CDrawSubscribeLinkCollectionIterator)
  178. FW_DEFINE_AUTO(CDrawLinkManager)
  179.     
  180. //========================================================================================
  181. //    class CDrawPublishLink
  182. //========================================================================================
  183.  
  184. //----------------------------------------------------------------------------------------
  185. //    CDrawPublishLink::CDrawPublishLink
  186. //----------------------------------------------------------------------------------------
  187.  
  188. CDrawPublishLink::CDrawPublishLink(Environment* ev, ODUpdateID updateID, 
  189.                                    FW_CPresentation* presentation, 
  190.                                    CDrawSelection* drawSelection,
  191.                                    FW_Boolean saveSelection) :
  192.     FW_CLinkSource(ev, updateID, presentation),
  193.     fDrawSelection(drawSelection),
  194.     fPublishedContent(NULL)
  195. {
  196.     CDrawContent* content = NULL;
  197.     if (saveSelection)        // Save the selected shapes so they can be published
  198.         content = fDrawSelection->GetDrawContent(ev);
  199.  
  200.     fPublishedContent = FW_NEW(CDrawLinkSourceContent, (ev, 
  201.                                             (CDrawPart*) presentation->GetPart(ev), 
  202.                                             content));
  203. }
  204.  
  205. //----------------------------------------------------------------------------------------
  206. //    CDrawPublishLink::~CDrawPublishLink
  207. //----------------------------------------------------------------------------------------
  208.  
  209. CDrawPublishLink::~CDrawPublishLink()
  210. {
  211.     delete fPublishedContent;
  212. }
  213.  
  214. //----------------------------------------------------------------------------------------
  215. //    CDrawPublishLink::LinkEstablished - Override
  216. //----------------------------------------------------------------------------------------
  217.  
  218. void CDrawPublishLink::LinkEstablished(Environment* ev)
  219. {
  220.     //---- Mark the collected shapes as published
  221.     CDrawContentShapeIterator ite(fPublishedContent);
  222.     for (CBaseShape* shape = ite.First(); ite.IsNotComplete(); shape = ite.Next())
  223.     {
  224.         shape->SetPublishLink(ev, this);
  225.     }
  226. }
  227.  
  228. //----------------------------------------------------------------------------------------
  229. //    CDrawPublishLink::ExternalizeLinkContent - Override
  230. //----------------------------------------------------------------------------------------
  231.  
  232. void CDrawPublishLink::ExternalizeLinkContent(Environment* ev, ODStorageUnit* linkSU)
  233. {    
  234.     // Remove extra properties (ODLinkSource::Clear removed only the content property)
  235.     FW_SURemoveProperty(ev, linkSU, kODPropContentFrame);
  236.     FW_SURemoveProperty(ev, linkSU, kODPropCloneKindUsed);
  237.  
  238.     // -- Pick a frame, any frame --
  239.     FW_CPresentationFrameIterator piter(ev, fPresentation);
  240.     FW_CFrame* frame = piter.First(ev);
  241.     FW_ASSERT(frame);
  242.  
  243.     fDataInterchange->ExternalizeData(ev, fPublishedContent, frame, linkSU, FW_kLinkStorage, kODCloneToLink);
  244. }
  245.  
  246. //----------------------------------------------------------------------------------------
  247. //    CDrawPublishLink::HasEmbeddedFrame
  248. //----------------------------------------------------------------------------------------
  249. FW_Boolean CDrawPublishLink::HasEmbeddedFrame(Environment* ev, ODFrame* odFrame)
  250. {
  251.     // Is odFrame involved in this link source? (called by DoUpdateLinks)
  252.  
  253.     // --- Find out whether odFrame is involved in any link source ---
  254.     if (odFrame->GetLinkStatus(ev) == kODInLinkSource)
  255.     {
  256.         // -- Find out whether odFrame is one of my frames --
  257.         FW_CFrame* fwFrame = FW_CFrame::ODtoFWFrame(ev, odFrame);
  258.         if (fwFrame)
  259.         {
  260.             CDrawContentShapeIterator iter(fPublishedContent);
  261.             for (CBaseShape* shape = iter.First(); iter.IsNotComplete(); shape = iter.Next())
  262.             {
  263.                 if ((shape->GetShapeType() == kProxyShape) && (((CProxyShape*)shape)->IsEmbeddedFrame(ev, odFrame)))
  264.                     return TRUE;
  265.             }
  266.         }
  267.     }
  268.  
  269.     return FALSE;
  270. }
  271.  
  272. //----------------------------------------------------------------------------------------
  273. //    CDrawPublishLink::GetFrameToRevealLink
  274. //----------------------------------------------------------------------------------------
  275. FW_CFrame* CDrawPublishLink::GetFrameToRevealLink(Environment* ev)
  276. {
  277.     // Just return the presentation's first display frame
  278.     FW_CPresentationFrameIterator piter(ev, fPresentation);
  279.     return piter.First(ev);
  280. }
  281.  
  282. //----------------------------------------------------------------------------------------
  283. //    CDrawPublishLink::DoSelect
  284. //----------------------------------------------------------------------------------------
  285. void CDrawPublishLink::DoSelect(Environment* ev, FW_CFrame* /*frame*/)
  286. {
  287.     // Select the published shapes
  288.     fDrawSelection->SelectContent(ev, fPublishedContent);
  289. }
  290.  
  291. //----------------------------------------------------------------------------------------
  292. //    CDrawPublishLink::AddShape
  293. //----------------------------------------------------------------------------------------
  294. void CDrawPublishLink::AddShape(Environment* ev, CBaseShape* shape)
  295. {
  296.     shape->SetPublishLink(ev, this);
  297.     fPublishedContent->AddShape(ev, shape);
  298. }
  299.  
  300. //----------------------------------------------------------------------------------------
  301. //    CDrawPublishLink::RemoveShape
  302. //----------------------------------------------------------------------------------------
  303. void CDrawPublishLink::RemoveShape(Environment* ev, CBaseShape* shape)
  304. {
  305.     fPublishedContent->RemoveShape(ev, shape);
  306. }
  307.  
  308. //----------------------------------------------------------------------------------------
  309. //    CDrawPublishLink::DoExternalizeLink
  310. //----------------------------------------------------------------------------------------
  311.  
  312. void CDrawPublishLink::DoExternalizeLink(Environment* ev, ODStorageUnit* storageUnit,
  313.                                          FW_CCloneInfo* cloneInfo)
  314. {
  315.     //--- Write the number of shapes in the link ---
  316.     unsigned long shapeCount = fPublishedContent->CountShapes();
  317.     FW_ASSERT(shapeCount != 0);
  318.     FW_CByteArray byteArray(&shapeCount, sizeof(unsigned long));
  319.     storageUnit->SetValue(ev, byteArray);
  320.  
  321.     //--- Write the externalization index for each shape in the link ---
  322.     CDrawContentShapeIterator iter(fPublishedContent);
  323.     for (CBaseShape* shape = iter.First(); iter.IsNotComplete(); shape = iter.Next())
  324.     {
  325.         short extIndex = shape->GetExternalizationIndex();
  326.         byteArray.Set(&extIndex, sizeof(short));
  327.         storageUnit->SetValue(ev, byteArray);
  328.     }
  329. }
  330.  
  331. //----------------------------------------------------------------------------------------
  332. //    CDrawPublishLink::IsEmpty
  333. //----------------------------------------------------------------------------------------
  334. FW_Boolean CDrawPublishLink::IsEmpty()
  335. {
  336.     return (fPublishedContent->CountShapes() == 0);
  337. }
  338.  
  339. //========================================================================================
  340. //    class CDrawSubscribeLink
  341. //========================================================================================
  342.  
  343. //----------------------------------------------------------------------------------------
  344. //    CDrawSubscribeLink::CDrawSubscribeLink
  345. //----------------------------------------------------------------------------------------
  346.  
  347. CDrawSubscribeLink::CDrawSubscribeLink(Environment* ev, ODLink* odLink, 
  348.                                         FW_CPresentation* presentation, 
  349.                                         CDrawSelection* drawSelection,
  350.                                         ODLinkInfo* linkInfo,
  351.                                         FW_Boolean createGroupShape) :
  352.     FW_CLinkDestination(ev, odLink, linkInfo, presentation),
  353.     fDrawPart((CDrawPart*) presentation->GetPart(ev)),
  354.     fDrawSelection(drawSelection),
  355.     fLinkedContent(NULL),
  356.     fGroupShape(NULL),
  357.     fFirstUpdate(true),
  358.     fFirstOffset(true)
  359. {
  360.     fUpdateOffset.Clear();
  361.  
  362.     //---- Create a new content object to hold the shapes in this link ----
  363.     fLinkedContent = FW_NEW(CDrawLinkContent, (ev, (CDrawPart*) presentation->GetPart(ev), this));
  364.  
  365.     if (createGroupShape)
  366.     {
  367.         //---- Create a new group shape to represent the linked shapes ---- 
  368.         fGroupShape = FW_NEW(CGroupShape, ());
  369.         fGroupShape->SetSubscribeLink(ev, this);
  370.     }
  371. }
  372.  
  373. //----------------------------------------------------------------------------------------
  374. //    CDrawSubscribeLink::~CDrawSubscribeLink
  375. //----------------------------------------------------------------------------------------
  376.  
  377. CDrawSubscribeLink::~CDrawSubscribeLink()
  378. {
  379.     FW_SOMEnvironment ev;
  380.     this->DeleteShapes(ev);
  381.     delete fLinkedContent;
  382.     fDrawPart->RemoveShapeFromPart(ev, fGroupShape);
  383.     delete fGroupShape;
  384. }
  385.  
  386. //---------------------------------------------------------------------------------------
  387. //    CDrawSubscribeLink::DoUpdateLink - Override
  388. //---------------------------------------------------------------------------------------
  389.  
  390. FW_Boolean CDrawSubscribeLink::DoUpdateLink(Environment* ev, ODStorageUnit* linkContentSU, ODPasteAsResult* embedAsInfo)
  391. {
  392.     // Find a frame to use for the scope frame
  393.     FW_CPresentationFrameIterator piter(ev, fPresentation);
  394.     FW_CFrame* frame = piter.First(ev);
  395.     FW_ASSERT(frame);
  396.  
  397.     if (!fFirstUpdate)
  398.         fLinkedContent->EmptyShapes(ev);    // remove linked shapes from our content
  399.  
  400.     // Read new shapes from the link SU into our content
  401.     FW_Boolean result = (fDataInterchange->InternalizeData(ev, fLinkedContent, frame, linkContentSU, 
  402.                                                 FW_kLinkStorage, kODCloneFromLink, embedAsInfo)
  403.                                                 != FW_kInternalizeFailed);
  404.     if (result)
  405.     {
  406.         // Merge newly-read link data with part data
  407.         this->UpdateLinkedContent(ev);
  408.  
  409.         // Force all frames to be redrawn
  410.         fPresentation->Invalidate(ev);
  411.     }
  412.     return result;
  413. }
  414.  
  415. //----------------------------------------------------------------------------------------
  416. //    CDrawSubscribeLink::UpdateLinkedContent
  417. //----------------------------------------------------------------------------------------
  418.  
  419. void CDrawSubscribeLink::UpdateLinkedContent(Environment* ev)
  420. {
  421.     // If we got this far, the link data was read successfully.
  422.  
  423.     if (fFirstUpdate)    // Add the group shape to the part
  424.     {
  425.         fDrawPart->AddShapeToPart(ev, fGroupShape);
  426.     }
  427.     else                // Delete obsolete data
  428.     {
  429.         fGroupShape->EmptyShapes(true);        // remove shapes and delete them
  430.     }
  431.  
  432.     // Roll the new shapes into the group shape
  433.     fLinkedContent->GroupShapes(ev, fGroupShape);
  434.  
  435.     if (!fFirstOffset && fUpdateOffset != FW_kZeroPoint)    // updating an existing link 
  436.     {
  437.         // move the linked shapes to their proper position
  438.         fGroupShape->OffsetShape(ev, fUpdateOffset.x, fUpdateOffset.y);
  439.     }
  440.  
  441.     // Redraw the new shapes
  442.     fLinkedContent->RedrawShapes(ev);
  443.  
  444.     fFirstUpdate = false;
  445.     fFirstOffset = false;
  446. }
  447.  
  448. //----------------------------------------------------------------------------------------
  449. //    CDrawSubscribeLink::BreakLink - Override
  450. //----------------------------------------------------------------------------------------
  451. void CDrawSubscribeLink::BreakLink(Environment* ev)
  452. {
  453.     FW_CLinkDestination::BreakLink(ev);
  454.  
  455.     // Remove linked shapes; if link is re-established new ones will be created
  456.     fLinkedContent->EmptyShapes(ev);    // remove shapes from content
  457.     fGroupShape->EmptyShapes(true);        // remove shapes and delete them
  458. }
  459.  
  460. //----------------------------------------------------------------------------------------
  461. //    CDrawSubscribeLink::RestoreLink - Override
  462. //----------------------------------------------------------------------------------------
  463. void CDrawSubscribeLink::RestoreLink(Environment* ev, FW_CPart* part)
  464. {
  465.     // Reset flag used in DoUpdateLink
  466.     fFirstUpdate = true;
  467.  
  468.     FW_CLinkDestination::RestoreLink(ev, part);
  469. }
  470.  
  471. //----------------------------------------------------------------------------------------
  472. //    CDrawSubscribeLink::SetGroupShape
  473. //----------------------------------------------------------------------------------------
  474. void CDrawSubscribeLink::SetGroupShape(Environment* ev, CGroupShape* groupShape)
  475. {
  476.     fGroupShape = groupShape;
  477.     groupShape->SetSubscribeLink(ev, this);
  478.  
  479.     // Add the grouped shapes to the linked content
  480.     CShapeCollectionIterator it(groupShape->GetShapeList());
  481.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  482.     {
  483.         fLinkedContent->AddShape(ev, shape);
  484.     }
  485.  
  486.     if (fLinkedContent->CountShapes() != 0)
  487.         fFirstUpdate = false;    // so that DoUpdateLink empties it before reading new shapes
  488. }
  489.  
  490. //----------------------------------------------------------------------------------------
  491. //    CDrawSubscribeLink::AddShape
  492. //----------------------------------------------------------------------------------------
  493. void CDrawSubscribeLink::AddShape(Environment* ev, CBaseShape* shape)
  494. {
  495.     // Called by Link Manager when internalizing destination links
  496.     fLinkedContent->AddShape(ev, shape);
  497.     fGroupShape->AddShape(shape);
  498. }
  499.  
  500. //----------------------------------------------------------------------------------------
  501. //    CDrawSubscribeLink::DeleteShapes
  502. //----------------------------------------------------------------------------------------
  503. void CDrawSubscribeLink::DeleteShapes(Environment* ev)
  504. {
  505.     // Called when undoing a Paste As (breaking a dest link)
  506.     fDrawSelection->CloseSelection(ev);
  507.     fLinkedContent->EmptyShapes(ev);    // remove shapes from content
  508.     fGroupShape->EmptyShapes(true);        // remove shapes and delete them
  509.  
  510.     // Remove the group shape from the part (destructor will delete it)
  511.     fDrawPart->RemoveShapeFromPart(ev, fGroupShape);
  512. }
  513.  
  514. //----------------------------------------------------------------------------------------
  515. //    CDrawSubscribeLink::SelectShapes
  516. //----------------------------------------------------------------------------------------
  517. void CDrawSubscribeLink::SelectShapes(Environment* ev)
  518. {
  519.     fDrawSelection->CloseSelection(ev);
  520.     fDrawSelection->AddToSelection(ev, fGroupShape, TRUE);
  521. }
  522.  
  523. //----------------------------------------------------------------------------------------
  524. //    CDrawSubscribeLink::DoExternalizeLink
  525. //----------------------------------------------------------------------------------------
  526.  
  527. void CDrawSubscribeLink::DoExternalizeLink(Environment* ev, ODStorageUnit* storageUnit,
  528.                                            FW_CCloneInfo* cloneInfo)
  529. {
  530.     //--- There is a single group shape in the link ---
  531.     FW_ASSERT(fGroupShape);
  532.     unsigned long shapeCount = 1;
  533.     FW_CByteArray byteArray(&shapeCount, sizeof(unsigned long));
  534.     storageUnit->SetValue(ev, byteArray);
  535.  
  536.     //--- Write the export index for the group shape ---
  537.     short extIndex = fGroupShape->GetExternalizationIndex();
  538.     byteArray.Set(&extIndex, sizeof(short));
  539.     storageUnit->SetValue(ev, byteArray);
  540. }
  541.  
  542. //----------------------------------------------------------------------------------------
  543. //    CDrawSubscribeLink::AdjustUpdateOffset
  544. //----------------------------------------------------------------------------------------
  545. void CDrawSubscribeLink::AdjustUpdateOffset(Environment* ev, const FW_CPoint& delta)
  546. {
  547.     fUpdateOffset += delta;
  548. }
  549.  
  550. //========================================================================================
  551. //    class CDrawLinkManager
  552. //========================================================================================
  553.  
  554. //----------------------------------------------------------------------------------------
  555. //    CDrawLinkManager constructor
  556. //----------------------------------------------------------------------------------------
  557.  
  558. CDrawLinkManager::CDrawLinkManager(Environment* ev, CDrawPart* part):
  559.     FW_CLinkManager(ev, part),
  560.     fDrawPart(part)
  561. {
  562. }
  563.  
  564. //----------------------------------------------------------------------------------------
  565. //    CDrawLinkManager destructor
  566. //----------------------------------------------------------------------------------------
  567.  
  568. CDrawLinkManager::~CDrawLinkManager()
  569. {
  570. }
  571.  
  572. //----------------------------------------------------------------------------------------
  573. //    CDrawLinkManager::NewLinkSource - Override
  574. //----------------------------------------------------------------------------------------
  575.  
  576. FW_CLinkSource* CDrawLinkManager::NewLinkSource(Environment* ev, ODUpdateID changeID, 
  577.                                                 FW_CPresentation* presentation)
  578. {
  579.     return new CDrawPublishLink(ev, changeID, 
  580.                                 presentation, fDrawPart->fDrawSelection, 
  581.                                 TRUE);    // saveSelection = TRUE
  582. }
  583.  
  584. //----------------------------------------------------------------------------------------
  585. //    CDrawLinkManager::NewLinkDestination - Override
  586. //----------------------------------------------------------------------------------------
  587.  
  588. FW_CLinkDestination* CDrawLinkManager::NewLinkDestination(Environment* ev, ODLink *odLink,
  589.                                                           ODLinkInfo* linkInfo,
  590.                                                           FW_CPresentation* presentation)
  591. {
  592.     return new CDrawSubscribeLink(ev, odLink, presentation, fDrawPart->fDrawSelection, linkInfo);
  593. }
  594.  
  595. //----------------------------------------------------------------------------------------
  596. //    CDrawLinkManager::DoChangeLinkStatus - Override
  597. //----------------------------------------------------------------------------------------
  598.  
  599. void CDrawLinkManager::DoChangeLinkStatus(Environment* ev, ODFrame* odFrame)
  600. {
  601.     // call ODFrame::ChangeLinkStatus on any embedded frames that are involved in a link
  602.     // when a link is created, broken, moved, etc.
  603.     // odFrame is the frame of this part whose link status has changed.
  604.     
  605.     FW_CEmbeddingFrame* frame = FW_CEmbeddingFrame::ODtoFWEmbeddingFrame(ev, odFrame);
  606.     if (frame)
  607.     {
  608.         ODLinkStatus linkStatus = odFrame->GetLinkStatus(ev);
  609.  
  610.         // Only need to propagate linkStatus to embedded frames that don't participate in
  611.         // any of this part's links; otherwise their local link status takes precedence.
  612.  
  613.         CDrawContentShapeIterator iter(fDrawPart->GetDrawContent());
  614.         for (CBaseShape* shape = iter.First(); iter.IsNotComplete(); shape = iter.Next())
  615.         {
  616.             if (shape->GetShapeType() == kProxyShape)
  617.             {
  618.                 CProxyShape* proxyShape = (CProxyShape*)shape;
  619.                 if (!proxyShape->IsPublished() && !proxyShape->IsSubscribed())
  620.                 {
  621.                     FW_CProxyEmbeddedFrameIterator efiter(ev, proxyShape);
  622.                     for (ODFrame* embFrame = efiter.First(ev); efiter.IsNotComplete(ev); embFrame = efiter.Next(ev))
  623.                         embFrame->ChangeLinkStatus(ev, linkStatus);
  624.                 }
  625.             }
  626.         }
  627.     }
  628. }
  629.  
  630. //----------------------------------------------------------------------------------------
  631. //    CDrawLinkManager::CreateLink - Override
  632. //----------------------------------------------------------------------------------------
  633. ODLinkSource* CDrawLinkManager::CreateLink(Environment* ev, ODByteArray* data)
  634. {
  635.     // CreateLink is overridden so that we can delete the pending clipboard publish link.
  636.     // This prevents the link spec from being re-used to create more than one link.
  637.  
  638.     FW_Boolean isLinkSpecOnClipboard = (GetPendingDropLink(ev) == NULL);
  639.     ODLinkSource* odLinkSource = FW_CLinkManager::CreateLink(ev, data);
  640.     if (isLinkSpecOnClipboard)
  641.         this->DeletePendingClipboardLink(ev);
  642.     return odLinkSource;
  643. }
  644.  
  645. //----------------------------------------------------------------------------------------
  646. //    CDrawLinkManager::UndoPasteAs
  647. //----------------------------------------------------------------------------------------
  648. void CDrawLinkManager::UndoPasteAs(Environment* ev, CDrawSubscribeLink* link)
  649. {
  650.     //--- Remove subscribed shapes from the document ---
  651.     link->DeleteShapes(ev);
  652. }
  653.  
  654. //----------------------------------------------------------------------------------------
  655. //    CDrawLinkManager::RedoPasteAs
  656. //----------------------------------------------------------------------------------------
  657. void CDrawLinkManager::RedoPasteAs(Environment* ev, CDrawSubscribeLink* link)
  658. {
  659. FW_UNUSED(ev);
  660. FW_UNUSED(link);
  661.  
  662.     // When the restored link is updated, new subscriber shapes will be created
  663. }
  664.  
  665. //----------------------------------------------------------------------------------------
  666. //    CDrawLinkManager::SelectSubscribedShapes
  667. //----------------------------------------------------------------------------------------
  668. void CDrawLinkManager::SelectSubscribedShapes(Environment* ev, CDrawSubscribeLink* link)
  669. {
  670.     fDrawPart->fDrawSelection->SelectContent(ev, (CDrawContent*) link->fLinkedContent);    /* PRIVATE */
  671. }
  672.  
  673. //----------------------------------------------------------------------------------------
  674. //    CDrawLinkManager::RevealLink - Override
  675. //----------------------------------------------------------------------------------------
  676. void CDrawLinkManager::RevealLink(Environment* ev, ODLinkSource* linkSource)
  677. {
  678.     CDrawPublishLink* sourceLink = (CDrawPublishLink*) ODtoFWLinkSource(ev, linkSource);
  679.     if (sourceLink == NULL) return;    // not our link!?
  680.  
  681.     // Choose a display frame for the source content
  682.     FW_CFrame* frame = sourceLink->GetFrameToRevealLink(ev);
  683.     if (frame)
  684.     {
  685.         // Ensure the display frame is revealed
  686.         if (!frame->GetWindow(ev)->IsActive(ev))
  687.             frame->GetWindow(ev)->Select(ev);        
  688.     
  689.         // ----- Activate the frame -----
  690.         if (!frame->HasSelectionFocus(ev))
  691.         {
  692.             FW_CFrameFacetIterator iter(ev, frame);    // find a facet
  693.             frame->PrivActivateFrame(ev, iter.First(ev));
  694.         }
  695.  
  696.         // Select the shape(s) that make up this link source
  697.         sourceLink->DoSelect(ev, frame);
  698.     }
  699. }
  700.  
  701. //----------------------------------------------------------------------------------------
  702. //    CDrawLinkManager::GetSUValue
  703. //----------------------------------------------------------------------------------------
  704.  
  705. ODULong CDrawLinkManager::GetSUValue(Environment* ev, ODStorageUnit* su, 
  706.                                      unsigned long size, void *buffer)
  707. {
  708.     // Convenience function; also makes code easier to read
  709.     FW_CByteArray ba;
  710.     ODULong bytesRead = su->GetValue(ev, size, ba);
  711.     ba.CopyBuffer(buffer, bytesRead);
  712.     
  713.     return bytesRead;
  714. }
  715.  
  716. //----------------------------------------------------------------------------------------
  717. //    CDrawLinkManager::DoInternalizeOneDestLink - Override
  718. //----------------------------------------------------------------------------------------
  719.  
  720. FW_CLinkDestination* CDrawLinkManager::DoInternalizeOneDestLink(Environment* ev, ODStorageUnit* storageUnit,
  721.                                                             ODLink* odLink, ODLinkInfo* linkInfo)
  722. {
  723.     //--- Create a subscriber object for this link ---
  724.     CDrawSubscribeLink* destLink = new CDrawSubscribeLink(ev, odLink, 
  725.                                                           fDrawPart->GetMainPresentation(), 
  726.                                                           fDrawPart->fDrawSelection, linkInfo,
  727.                                                           false);    // don't create group shape
  728.  
  729.     //--- Read the number of shapes in the link ---
  730.     unsigned long shapeCount;
  731.     GetSUValue(ev, storageUnit, sizeof(unsigned long), &shapeCount);
  732.     FW_ASSERT(shapeCount == 1);    // There should be a single group shape
  733.  
  734.     //--- Read each shape index and add the shape to the source link ---
  735.     short extIndex;
  736.     GetSUValue(ev, storageUnit, sizeof(short), &extIndex);
  737.     CBaseShape* shape = fDrawPart->FindShapeWithIndex(extIndex);
  738.     FW_ASSERT(shape);
  739.     if (shape && shape->GetShapeType() == kGroupShape)
  740.     {
  741.         destLink->SetGroupShape(ev, (CGroupShape*)shape);
  742.     }
  743.  
  744.     return destLink;
  745. }
  746.  
  747. //----------------------------------------------------------------------------------------
  748. //    CDrawLinkManager::DoInternalizeOneSourceLink - Override
  749. //----------------------------------------------------------------------------------------
  750.  
  751. FW_CLinkSource* CDrawLinkManager::DoInternalizeOneSourceLink(Environment* ev, 
  752.                                                               ODStorageUnit* storageUnit,
  753.                                                               ODUpdateID updateID)
  754. {
  755.     //--- Create a publish object for this source link ---
  756.     CDrawPublishLink* sourceLink = new CDrawPublishLink(ev, updateID, fDrawPart->GetMainPresentation(), fDrawPart->fDrawSelection, FALSE);
  757.  
  758.     //--- Read the number of shapes in the link ---
  759.     unsigned long shapeCount;
  760.     GetSUValue(ev, storageUnit, sizeof(unsigned long), &shapeCount);
  761.  
  762.     //--- Read each shape index and add the shape to the source link ---
  763.     unsigned long shapesInLink = 0;
  764.     short extIndex;
  765.     while (shapeCount > 0)
  766.     {
  767.         GetSUValue(ev, storageUnit, sizeof(short), &extIndex);
  768.         CBaseShape* shape = fDrawPart->FindShapeWithIndex(extIndex);
  769.         if (shape)
  770.         {
  771.             sourceLink->AddShape(ev, shape);
  772.             shapesInLink++;
  773.         }
  774.         shapeCount--;
  775.     }
  776.  
  777.     //--- If no linked shapes were found, discard the link ---
  778.     if (shapesInLink == 0)
  779.     {
  780.         delete sourceLink;
  781.         sourceLink = NULL;
  782.     }
  783.  
  784.     return sourceLink;
  785. }
  786.  
  787. //----------------------------------------------------------------------------------------
  788. //    CDrawLinkManager::GetSourceLinkFormat - Override
  789. //----------------------------------------------------------------------------------------
  790.  
  791. ODValueType CDrawLinkManager::GetSourceLinkFormat(Environment* ev)
  792. {    
  793.     return kPublishFormat;
  794. }
  795.  
  796. //----------------------------------------------------------------------------------------
  797. //    CDrawLinkManager::GetDestLinkFormat - Override
  798. //----------------------------------------------------------------------------------------
  799.  
  800. ODValueType CDrawLinkManager::GetDestLinkFormat(Environment* ev)
  801. {    
  802.     return kSubscribeFormat;
  803. }
  804.